package mcpinit

import (
	"context"
	"log"
	"os"
	"time"

	mcpregister "ai-mcp/mcp-register"

	"github.com/mark3labs/mcp-go/server"
)

// FilesHandleMcp 文件处理MCP服务结构体
// 用于初始化和管理文件处理相关的MCP服务实例
// 字段：
//   - McpService: MCP服务实例指针，用于注册和管理文件处理工具
//   - sseServer: SSE服务器实例，用于处理服务器发送事件
//   - streamableServer: 流式HTTP服务器实例
//   - stdio: 标准输入输出服务器实例
//   - ctx: 上下文，用于控制服务的生命周期
//   - cancel: 取消函数，用于优雅地停止服务
//   - fileTools: 文件处理工具列表
//   - fileResources: 文件处理资源列表
//   - filePrompts: 文件处理提示词列表

type FilesHandleMcp struct {
	McpService       *server.MCPServer
	sseServer        *server.SSEServer
	streamableServer *server.StreamableHTTPServer
	stdio            *server.StdioServer
	ctx              context.Context
	cancel           context.CancelFunc
}

// NewFilesHandleMcp 创建并初始化文件处理MCP服务实例
// 返回值：
//   - *FilesHandleMcp: 初始化完成的文件处理MCP服务实例指针
//
// 说明：
//   - 创建MCP服务实例并设置服务名称为"files_handle_mcp"
//   - 初始化所有必要的字段，包括工具、资源和提示词列表
//   - 准备注册文件处理工具
func NewFilesHandleMcp() *FilesHandleMcp {
	// 创建上下文用于控制服务生命周期
	ctx, cancel := context.WithCancel(context.Background())

	// 创建MCP服务实例
	mcpService := server.NewMCPServer(
		"files_handle_mcp",
		"1.0.0",
	)

	//初始化工具
	mcpregister.RegisterFilesTools(mcpService)

	//初始化资源

	//初始化提示词

	log.Println("文件处理MCP服务实例创建完成，已初始化工具、资源和提示词列表")

	return &FilesHandleMcp{
		McpService: mcpService,
		ctx:        ctx,
		cancel:     cancel,
	}
}

// InitFilesTools 初始化所有文件处理工具
// 功能：
//   - 检查MCP服务是否已正确初始化
//   - 注册所有文件处理相关的工具函数到MCP服务中
// 错误处理：
//   - 如果MCP服务未初始化，则记录致命错误并终止程序

func (filesMcp *FilesHandleMcp) InitFilesTools() {
	// 检查MCP服务是否已初始化
	if filesMcp.McpService == nil {
		log.Fatal("MCP服务未初始化，请确保在调用InitFilesTools前正确创建了MCP服务实例")
	}

	log.Println("开始注册文件处理工具...")
	// 注册所有文件处理相关的工具函数
	mcpregister.RegisterFilesTools(filesMcp.McpService)
	log.Println("文件处理工具注册完成")
}

// SSEStart 启动SSE服务
// 功能：
//   - 检查MCP服务是否已正确初始化
//   - 启动SSE服务，允许客户端通过SSE连接接收实时事件
//   - 从环境变量获取端口配置
//
// 返回值：
//   - <-chan error: 服务启动结果的通道
//
// 错误处理：
//   - 如果MCP服务未初始化，则记录致命错误并终止程序
//   - 记录启动过程中的关键信息
func (filesMcp *FilesHandleMcp) SSEStart() <-chan error {
	// 检查MCP服务是否已初始化
	if filesMcp.McpService == nil {
		log.Fatal("MCP服务未初始化，无法启动SSE服务")
	}

	errChan := make(chan error, 1)

	// 从环境变量获取端口，如果未设置则使用默认端口
	envPort := os.Getenv("MCP_SSE_PORT")
	if envPort == "" {
		envPort = "8080" // 默认端口
	}

	address := ":" + envPort

	// 创建并保存SSE服务器实例
	sseServer := server.NewSSEServer(
		filesMcp.McpService,
		server.WithSSEEndpoint("/file/sse"),
		server.WithBaseURL("http://localhost"),
	)
	filesMcp.sseServer = sseServer

	log.Printf("[MCP] 开始启动SSE服务，监听端口: %s", address)

	// 在goroutine中启动服务
	go func() {
		if err := sseServer.Start(address); err != nil {
			errChan <- err
			close(errChan)
		}
	}()

	// 等待服务启动
	time.Sleep(100 * time.Millisecond)
	log.Printf("[MCP] SSE服务已启动 (PID: %d)", os.Getpid())
	log.Printf("[MCP] 服务地址: http://localhost:%s", envPort)
	log.Printf("[MCP] 可用工具: 文件处理相关工具")

	return errChan
}

// SSEStop 停止SSE服务
// 功能：
//   - 检查SSE服务是否已启动
//   - 优雅地停止SSE服务，关闭所有客户端连接
//   - 释放相关资源
//
// 错误处理：
//   - 记录停止过程中的错误信息
func (filesMcp *FilesHandleMcp) SSEStop() {
	if filesMcp.sseServer == nil {
		log.Println("SSE服务未启动，无需停止")
		return
	}

	log.Println("开始停止SSE服务...")

	// 优雅地关闭服务器
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := filesMcp.sseServer.Shutdown(ctx); err != nil {
		log.Printf("SSE服务停止出错: %v\n", err)
	} else {
		log.Println("SSE服务已成功停止")
	}

	// 重置服务器实例
	filesMcp.sseServer = nil
}

// StreamableStart 启动流式处理服务
// 功能：
//   - 检查MCP服务是否已正确初始化
//   - 启动流式处理服务，允许客户端通过流式连接接收实时事件
//   - 从环境变量获取端口配置
//
// 返回值：
//   - <-chan error: 服务启动结果的通道
//
// 错误处理：
//   - 如果MCP服务未初始化，则记录致命错误并终止程序
//   - 记录启动过程中的关键信息
func (filesMcp *FilesHandleMcp) StreamableStart() <-chan error {
	// 检查MCP服务是否已初始化
	if filesMcp.McpService == nil {
		log.Fatal("MCP服务未初始化，无法启动流式处理服务")
	}

	errChan := make(chan error, 1)

	// 从环境变量获取端口，如果未设置则使用默认端口
	envPort := os.Getenv("MCP_STREAM_PORT")
	if envPort == "" {
		envPort = "8081" // 默认端口
	}

	address := ":" + envPort

	// 创建并保存流式HTTP服务器实例
	streamableServer := server.NewStreamableHTTPServer(
		filesMcp.McpService,
		server.WithEndpointPath("/file/streamable"),
	)
	filesMcp.streamableServer = streamableServer

	log.Printf("[MCP] 开始启动流式处理服务，监听端口: %s", address)

	// 在goroutine中启动服务
	go func() {
		if err := streamableServer.Start(address); err != nil {
			errChan <- err
			close(errChan)
		}
	}()

	// 等待服务启动
	time.Sleep(100 * time.Millisecond)
	log.Printf("[MCP] 流式处理服务已启动 (PID: %d)", os.Getpid())
	log.Printf("[MCP] 服务地址: http://localhost:%s", envPort)
	log.Printf("[MCP] 可用功能: 文件处理流式响应")

	return errChan
}

// StreamableStop 停止流式处理服务
// 功能：
//   - 检查流式处理服务是否已启动
//   - 优雅地停止流式处理服务，关闭所有客户端连接
//   - 释放相关资源
//
// 错误处理：
//   - 记录停止过程中的错误信息
func (filesMcp *FilesHandleMcp) StreamableStop() {
	if filesMcp.streamableServer == nil {
		log.Println("流式处理服务未启动，无需停止")
		return
	}

	log.Println("开始停止流式处理服务...")

	// 优雅地关闭服务器
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := filesMcp.streamableServer.Shutdown(ctx); err != nil {
		log.Printf("流式处理服务停止出错: %v\n", err)
	} else {
		log.Println("流式处理服务已成功停止")
	}

	// 重置服务器实例
	filesMcp.streamableServer = nil
}

// StartAllServices 启动所有服务
// 功能：
//   - 启动SSE服务
//   - 启动流式处理服务
//
// 返回值：
//   - []<-chan error: 包含所有服务启动结果通道的切片
func (filesMcp *FilesHandleMcp) StartAllServices() []<-chan error {
	log.Println("开始启动所有服务...")

	// 启动各个服务
	errChans := make([]<-chan error, 0, 2)
	errChans = append(errChans, filesMcp.SSEStart())
	errChans = append(errChans, filesMcp.StreamableStart())

	log.Println("所有服务启动完成")
	return errChans
}

// StopAllServices 停止所有服务
// 功能：
//   - 停止SSE服务
//   - 停止流式处理服务
//   - 取消上下文，通知所有依赖该上下文的组件停止
//   - 释放所有相关资源
func (filesMcp *FilesHandleMcp) StopAllServices() {
	log.Println("开始停止所有服务...")

	// 停止各个服务
	filesMcp.SSEStop()
	filesMcp.StreamableStop()

	// 取消上下文，通知所有组件停止
	if filesMcp.cancel != nil {
		filesMcp.cancel()
		log.Println("服务上下文已取消")
	}

	log.Println("所有服务已成功停止")
}
